了解完 K nearest neighbors 的理論後,我們今天會透過著名的 iris 資料集來實做它。
首先透過使用 scikit-learn
的 library 來實做
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import plotly.express as px
import seaborn as sns
iris = pd.read_csv("../input/iris/Iris.csv") #Load Data
iris.drop('Id',inplace=True,axis=1) #Drop Id column
這裡注意到,資料集的路徑必須隨檔案路徑更改
之後移除不必要的 column Id
X = iris.iloc[:,:-1] #Set our training data
y = iris.iloc[:,-1] #Set training labels
定義資料集的資料跟標籤
X_train, X_test, y_train, y_test = train_test_split(X.values, y.values, test_size = 0.2, random_state=42) #split the data into traing and validating
from sklearn.neighbors import KNeighborsClassifier
skmodel = KNeighborsClassifier(n_neighbors=7)
skmodel.fit(X_train, y_train)
sk_predictions = skmodel.predict(X_test)
sk_accuracy = compute_accuracy(y_test, sk_predictions)
print(f" sklearn-model got accuracy score of : {sk_accuracy}")
k 值目前設 7
這裡我們得到使用 KNN 分類的準確率是 96.67 %
class KNN:
def __init__(self, n_neighbors=5):
self.n_neighbors = n_neighbors
def euclidean_distance(self, x1, x2):
return np.linalg.norm(x1 - x2)
def fit(self, X_train, y_train):
self.X_train = X_train
self.y_train = y_train
def predict(self, X):
# Create empty array to store the predictions
predictions = []
# Loop over X examples
for x in X:
# Get prediction using the prediction helper function
prediction = self._predict(x)
# Append the prediction to the predictions list
predictions.append(prediction)
return np.array(predictions)
def _predict(self, x):
# Create empty array to store distances
distances = []
# Loop over all training examples and compute the distance between x and all the training examples
for x_train in self.X_train:
distance = self.euclidean_distance(x, x_train)
distances.append(distance)
distances = np.array(distances)
# Sort by ascendingly distance and return indices of the given n neighbours
n_neighbors_idxs = np.argsort(distances)[: self.n_neighbors]
# Get labels of n-neighbour indexes
labels = self.y_train[n_neighbors_idxs]
labels = list(labels)
# Get the most frequent class in the array
most_occuring_value = max(labels, key=labels.count)
return most_occuring_value
__init__(self, n_neighbors)
定義 k 的初始值
euclidean_distance(self, x1, x2)
計算歐幾里得距離
假設 維點,點 和 ,而其歐氏距離為
fit(self, X_train, y_train)
此處接收訓練數據集 X_train
和對應的目標標籤 y_train
。
它將訓練數據集和目標標籤存儲在類別的實例變數 self.X_train
和 self.y_train
中,以供後續使用。
predict(self, X)
此處接收測試數據集 X
,並返回對每個測試數據點的預測類別標籤。
它遍歷測試數據集中的每個數據點 x
,並調用 _predict
方法來獲得每個數據點的預測類別。
_predict(self, x)
首先計算測試點 x
與訓練數據集中每個訓練點之間的歐式距離,並將這些距離存儲在 distances
列表中。
然後,使用 argsort
函數對距離列表進行排序,以獲得最接近 x
的前 n_neighbors
個鄰居的索引。
接下來,從訓練數據集中檢索這些鄰居的標籤,並將這些標籤存儲在 labels
列表中。
最後找到 labels
中出現最頻繁的類別標籤,並將其視為 x
的預測類別標籤,然後回傳這個預測類別。
與前面 Sklearn Implementation 一樣,我們得到使用 KNN 分類的準確率是 96.67 %
詳細 Notebook 可以參考 Kaggle
明天要進入真實實戰部份,會透過 Kaggle competition - Spaceship Titanic 來演練